﻿/**
as3app - An open-source ActionScript 3.0 Library developed to assist 
in creating simple visual controls/data binding/asset loading for the
Flash player platform.

http://code.google.com/p/as3app/

Copyright (c) 2011 M. K. Chowdhury, All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package as3app.tooltip 
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.MouseEvent;
	import flash.ui.Mouse;
	/**
	 * ...
	 * @author Muntasir Kabir Chowdhury
	 */
	public class Tooltip 
	{
		protected var _gapX:int = 15, _gapY:int = 10;
		
		protected var _datas:Array = new Array();
		protected var _topMostDisplayObjectContainer:DisplayObjectContainer = null;
		protected static var _instance:Tooltip = null;
		
		
		
		public function Tooltip(singelton:TooltipSingeltonBlocker,topMostDisplayObject:DisplayObjectContainer) 
		{
			if (singelton == null) 
			{
				throw("as3app.tooltip.Tooltip : Error. Can not initiate abstract class.");	
			}
			_topMostDisplayObjectContainer = topMostDisplayObject;
		}

		
		public static function Init(topMostDisplayObject:DisplayObjectContainer):Boolean
		{
			if (_instance == null && topMostDisplayObject != null) 
			{
				_instance = new Tooltip(new TooltipSingeltonBlocker(), topMostDisplayObject);
				return true;
			}
			return false;
		}
		
		public static const TYPE_OF_STATIC:int = 1;
		public static const TYPE_OF_STATIC_COMPLEX:int = 2;
		public static const TYPE_OF_DYNAMIC:int = 3;
		public static const TYPE_OF_DYNAMIC_COMPLEX:int = 4;
		public static const TYPE_OF_DYNAMIC_UNIQUE:int = 5;
		
		
		
		
		public static function Register(control:DisplayObject, typeOfTooltip:int, moveOnMouseMove:Boolean=true, ...param)
		{
			var object:Object = new Object();
			
			
			// Create tooltip instance
			
			var tooltip:ITooltip = null;
			switch(typeOfTooltip)
			{
				case TYPE_OF_STATIC:
					
					tooltip = new TypeOfStaticTooltip(param) as ITooltip;
					break;
					
				case TYPE_OF_DYNAMIC:
					if (param.length > 1) tooltip = new TypeOfDynamicTooltip(param[0] as Function, int(param[1])) as ITooltip;
					else tooltip = new TypeOfDynamicTooltip(param[0] as Function, 500) as ITooltip;
					break;
			}
			object.TooltipInstance = tooltip;
			
			// Store targeted control
			object.Control = control;
			
			// set event handlers 
			object.MouseOverHandler = 
				function(e1:MouseEvent)
				{
					var displayObject:DisplayObject = tooltip.StartToolTip();
					
					if ((e1 as MouseEvent).stageX < _instance._topMostDisplayObjectContainer.width / 2)
					{
						displayObject.x = (e1 as MouseEvent).stageX + _instance._gapX;
					}
					else
					{
						displayObject.x = (e1 as MouseEvent).stageX - _instance._gapX - displayObject.width;
					}
					
					
					if ((e1 as MouseEvent).stageY < _instance._topMostDisplayObjectContainer.height / 2)
					{
						displayObject.y = (e1 as MouseEvent).stageY + _instance._gapY;
					}
					else
					{
						displayObject.y = (e1 as MouseEvent).stageY - _instance._gapY - displayObject.height;
					}
					
					_instance._topMostDisplayObjectContainer.addChild(displayObject);
				};
			
			object.MouseOutHandler =  
				function(e2:MouseEvent)
				{
					_instance._topMostDisplayObjectContainer.removeChild(tooltip.StopTooltip());
				};
			
			
			object.MouseMoveHandler =  
				function(e3:MouseEvent)
				{
					var displayObject:DisplayObject = tooltip.GetToolTip();
					//trace("mouse: (" + (e3 as MouseEvent).stageX + "," + (e3 as MouseEvent).stageY + ")  |   stage: (" + _instance._topMostDisplayObjectContainer.width + "," + _instance._topMostDisplayObjectContainer.height + ")" +
					//	"popup:  (" + displayObject.width + "," + displayObject.height + ")");
					if ((e3 as MouseEvent).stageX < _instance._topMostDisplayObjectContainer.width / 2)
					{
						displayObject.x = (e3 as MouseEvent).stageX + _instance._gapX;
					}
					else
					{
						displayObject.x = (e3 as MouseEvent).stageX - _instance._gapX - displayObject.width;
					}
					
					
					if ((e3 as MouseEvent).stageY < _instance._topMostDisplayObjectContainer.height / 2)
					{
						displayObject.y = (e3 as MouseEvent).stageY + _instance._gapY;
					}
					else
					{
						displayObject.y = (e3 as MouseEvent).stageY - _instance._gapY - displayObject.height;
					}
					
				};
			
			// store data
			_instance._datas.push(object);
			
			// adding event handlers to controls
			control.addEventListener(MouseEvent.MOUSE_OVER, object.MouseOverHandler as Function);
			if(moveOnMouseMove) control.addEventListener(MouseEvent.MOUSE_MOVE, object.MouseMoveHandler as Function);
			control.addEventListener(MouseEvent.MOUSE_OUT, object.MouseOutHandler as Function);
		}
		
		
		
		
		
		/*
		 * Styling Component
		 */
		protected static var _tooltipParaColor:int = 0x99AAEE;
		public static function get ParaColor():int { return _tooltipParaColor; }
		public static function set ParaColor(tooltipParaColor:int) { _tooltipParaColor = tooltipParaColor; }
		
		 
		protected static var _tooltipParaGap:int = 8;
		public static function get ParaGap():int { return _tooltipParaGap; }
		public static function set ParaGap(tooltipParaGap:int) { _tooltipParaGap = tooltipParaGap; }
		
		
		protected static var _tooltipWidth:int = 400;
		public static function get Width():int { return _tooltipWidth; }
		public static function set Width(tooltipWidth:int) { _tooltipWidth = tooltipWidth; }
		
		protected static var _tooltipBorderWidth:int = 8;
		public static function get BorderWidth():int { return _tooltipBorderWidth; }
		public static function set BorderWidth(tooltipBorderWidth:int) { _tooltipBorderWidth = tooltipBorderWidth; }
		
		
		protected static var _tooltipCornerEllipseWidth:int = 5;
		public static function get CornerEllipseWidth():int { return _tooltipCornerEllipseWidth; }
		public static function set CornerEllipseWidth(tooltipCornerEllipseWidth:int) { _tooltipCornerEllipseWidth = tooltipCornerEllipseWidth; }
		
		
		
		protected static var _tooltipSoftOn:Number = 0.5;
		public static function get TooltipSoftOn():Number { return _tooltipSoftOn; }
		public static function set TooltipSoftOn(tooltipSoftOn:Number) { _tooltipSoftOn = tooltipSoftOn; }
		
		
		
		protected static var _tooltipSoftOnTime:int = 200;
		public static function get TooltipSoftOnTime():int { return _tooltipSoftOnTime; }
		public static function set TooltipSoftOnTime(tooltipSoftOnTime:int) { _tooltipSoftOnTime = tooltipSoftOnTime; }
		
		
		
		protected static var _tooltipDelay:int = 100;
		public static function get TooltipDelay():int { return _tooltipDelay; }
		public static function set TooltipDelay(tooltipDelay:int) { _tooltipDelay = tooltipDelay; }
	}

}